package facebooksharing;

import facebook4j.Facebook;
import facebook4j.FacebookException;
import facebook4j.FacebookFactory;
import facebook4j.Group;
import facebook4j.GroupMember;
import facebook4j.Media;
import facebook4j.PostUpdate;
import facebook4j.auth.AccessToken;
import facebook4j.internal.org.json.JSONArray;
import facebook4j.internal.org.json.JSONException;
import facebook4j.internal.org.json.JSONObject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class FacebookSharing {

    private String appId;
    private String appSecret;
    private Facebook facebook;

    private FacebookSharing() {
        FileInputStream stream = null;
        try {
            stream = new FileInputStream(new File("./facebook-app.properties"));
            Properties prop = new Properties();
            prop.load(stream);
            appId = prop.getProperty("app.id");
            appSecret = prop.getProperty("app.secret");
        } catch (FileNotFoundException ex) {
            Logger.getLogger(FacebookSharing.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(FacebookSharing.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                stream.close();
            } catch (IOException ex) {
                Logger.getLogger(FacebookSharing.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void setAccessToken(String accessToken) throws FacebookException {
        facebook = new FacebookFactory().getInstance();
        facebook.setOAuthAppId(appId, appSecret);
        facebook.setOAuthAccessToken(new AccessToken(accessToken, null));
    }

    public List<Group> getGroups() throws FacebookException {
        return facebook.getGroups();
    }

    public List<Page> getPages() throws FacebookException, JSONException {
        String query = "SELECT page_id, name FROM page WHERE page_id in (SELECT page_id FROM page_fan WHERE uid=me())";
        JSONArray jsonArray = facebook.executeFQL(query);
        List<Page> pages = new ArrayList<Page>();
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            pages.add(new Page(jsonObject.getString("page_id"), jsonObject.getString("name")));
        }
        return pages;
    }

    public Group getGroup(String id) throws FacebookException {
        return facebook.getGroup(id);
    }

    public List<GroupMember> getGroupMembers(String id) throws FacebookException {
        return facebook.getGroupMembers(id);
    }

    public void postPhoto(Group group, File file, String message) throws FacebookException {
        facebook.postPhoto(group.getId(), new Media(file), message, null, false);
    }

    public void postPhoto(Page page, File file, String message) throws FacebookException {
        facebook.postPhoto(page.getId(), new Media(file), message, null, false);
    }

    public void postText(Group group, String message) throws FacebookException {
        PostUpdate post = new PostUpdate(message);
        facebook.postGroupFeed(group.getId(), post);
    }

    public void postText(Page page, String message) throws FacebookException {
        facebook.postStatusMessage(page.getId(), message);
    }

    public void postLink(Group group, String link, String message) throws FacebookException, MalformedURLException {
        facebook.postLink(group.getId(), new URL(link), message);
    }

    public void postLink(Page page, String link, String message) throws FacebookException, MalformedURLException {
        facebook.postLink(page.getId(), new URL(link), message);
    }
    private static FacebookSharing instance;

    static {
        instance = new FacebookSharing();
    }

    public static FacebookSharing getInstance() {
        return instance;
    }

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(FacebookSharing.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(FacebookSharing.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(FacebookSharing.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(FacebookSharing.class.getName()).log(Level.SEVERE, null, ex);
        }

        Janela janela = new Janela();
        janela.setVisible(true);

        //FacebookSharing sharing = FacebookSharing.getInstance();
        try {
            //sharing.setAccessToken("CAADl098pC8UBALZAjargxCWJYPVFTbmOJfBNk6FRbrjrCmE6luap6WcBe4aKXAAQLEyKTbD73ZAOcqbaetiRYLyUVxGJBtnUaEzKibLEgAL4KrWA8PCFcIuqId4qlsoeHv0wEpq1O8bwqrZBilFfv05ZA5tM4rsZD");

            /*for (Page page : sharing.getPages()) {
             System.out.println(page.getName() + " - " + page.getId());
             }*/
            //sharing.postText(new Page("310503255735467", "Conselho Branco - Sociedade Tolkien"), "teste");
            //Toca RJ - 230478460368727
            //Toca Rio de Janeiro Conselho Branco - 337070459661072

            /*List<GroupMember> tocaRJToRemove = sharing.getGroupMembers("230478460368727");
             List<GroupMember> tocaRJToStay = sharing.getGroupMembers("337070459661072");

             Map<String, GroupMember> map = new HashMap<String, GroupMember>();
             Map<String, GroupMember> merged = new HashMap<String, GroupMember>();
             Map<String, GroupMember> notMerged = new HashMap<String, GroupMember>();


             for (GroupMember member : tocaRJToStay) {
             map.put(member.getId(), member);
             }

             for (GroupMember member : tocaRJToRemove) {
             if (map.containsKey(member.getId())) {
             merged.put(member.getId(), member);
             } else {
             notMerged.put(member.getId(), member);
             }
             }

             System.out.println("Cadastrados nos dois grupos: ");

             for (GroupMember member : merged.values()) {
             System.out.println(member.getName());
             }

             System.out.println();
             System.out.println("Cadastrados só no grupo a ser removido: ");

             for (GroupMember member : notMerged.values()) {
             System.out.println(member.getName());
             }*/
        } catch (Exception ex) {
            Logger.getLogger(FacebookSharing.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
